<?php
namespace Sdk\Winit;

class CallApiUtil
{
    const TOKEN = 'F5F537F4CAA69D019DC63FA0CC10CD17';
    const APP_KEY = 'kim_pan@echamp.com.cn';
    const PLATFORM = 'ec';
    const VERSION = '1.0';
    const SIGN_METHOD = 'md5';
    const FORMAT = 'json';
    const CONNECT_TIMEOUT = 120;
    const READ_TIMEOUT = 120;
    const CLIENT_SECRET = 'NGUXZTJKMMYTODG5YS00MWFILTLHYTMTMJIZZWJKMJDKZGVIODC1MTU1NZEZMZU0NTK1OTC=';
    const CLIENT_ID = 'NDKYMTVKZMUTMWZLOC00NZY4LTG3M2ETMTDHNJU1MDCWNWZI';
    const SERVICE_URL = 'https://openapi.winit.com.cn/openapi/service';

    public static function callWinitApi($action, $data)
    {
        ksort($data);
        $data = json_encode($data);
        $postData = self::buildSignData($action, $data);
        $postData = array_merge($postData, self::getSystemParams($action), ['client_id' => self::CLIENT_ID]);
        //请求接口获取数据
        ksort($postData);
        $postData['data'] = json_decode($postData['data'], true);
        $response = self::postCurl(self::SERVICE_URL, json_encode($postData));
        $responseArr = json_decode($response, true);
        return $responseArr;
    }


    public static function postCurl($url, $data)
    {
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/json'));
        curl_setopt($ch, CURLOPT_POST, 1);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        if (self::CONNECT_TIMEOUT) {
            curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, self::CONNECT_TIMEOUT);
        }
        if (self::READ_TIMEOUT) {
            curl_setopt($ch, CURLOPT_TIMEOUT, self::READ_TIMEOUT);
        }
        $response = curl_exec($ch);
        unset($data);
        try {
            if (curl_errno($ch)) {
                throw new \Exception(curl_error($ch), 0);
            } else {
                $httpStatusCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
                if ($httpStatusCode !== 200) {
                    throw new \Exception($response, $httpStatusCode);
                }
            }
        } finally {
            curl_close($ch);
        }

        return $response;
    }


    public static function buildSignData($action, $data)
    {
        $postData = [
            'action' => $action,
            'data' => $data
        ];
        $systemParam = self::getSystemParams($action);
        $postData = array_merge($systemParam, $postData);
        list($postData['sign'], $postData['client_sign']) = [
            self::generateSign($postData),
            self::generateSign($postData, 'client')
        ];
        return $postData;
    }



    private static function getSystemParams($action = '')
    {
        $systemParam = [
            'app_key' => self::APP_KEY,
            'format' => self::FORMAT,
            'platform' => self::PLATFORM,
            'sign_method' => self::SIGN_METHOD,
            'timestamp' => self::getTimestamp(),
            'version' => in_array($action, ['queryWarehouseStorage']) ? '3.0' : self::VERSION
        ];
        return $systemParam;
    }


    private static function getTimestamp()
    {
        return date('Y-m-d H:i:s');
    }

    private static function generateSign($params, $type = 'account')
    {
        ksort($params);
        $stringToBeSigned = ('account' == $type) ? self::TOKEN : self::CLIENT_SECRET;
        foreach ($params as $k => $v) {
            $stringToBeSigned .= "$k$v";
        }
        unset($k, $v);
        $stringToBeSigned .= ('account' == $type) ? self::TOKEN : self::CLIENT_SECRET;
        return strtoupper(md5($stringToBeSigned));
    }
}